﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using LCA.Web.Controls;
using LCA.Utils;

public partial class Paginator : System.Web.UI.UserControl
{
    private IPageableControl controlToPaginate;
    private Paginator linkedPaginator;

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            RefreshComponents();
        }
    }

    protected void Page_PreRender(object sender, EventArgs e)
    {
        this.Visible = ItemCount > 0;
    }

    public event EventHandler PageIndexChanged;
    public event EventHandler PageSizeChanged;

    protected virtual void OnPageIndexChanged(EventArgs e)
    {
        if (ControlToPaginate != null)
        {
            ControlToPaginate.ChangePageIndex(this.PageIndex);
        }
        if (LinkedPaginator != null)
        {
            LinkedPaginator.PageIndex = this.PageIndex;
        }

        if (PageIndexChanged != null)
        {
            // Invokes the delegates.
            PageIndexChanged(this, e);
        }
    }

    public void ChangePageSize()
    {
        OnPageSizeChanged(new EventArgs());
    }

    protected virtual void OnPageSizeChanged(EventArgs e)
    {
        if (ControlToPaginate != null)
        {
            ControlToPaginate.ChangePageSize(this.PageSize);
        }
        if (LinkedPaginator != null)
        {
            LinkedPaginator.PageSize = this.PageSize;
        }

        if (PageSizeChanged != null)
        {
            // Invokes the delegates.
            PageSizeChanged(this, e);
        }
    }

    public IPageableControl ControlToPaginate
    {
        get
        {
            return controlToPaginate;
        }
        set
        {
            controlToPaginate = value;
        }
    }

    public Paginator LinkedPaginator
    {
        get
        {
            return linkedPaginator;
        }
        set
        {
            linkedPaginator = value;
        }
    }

    public bool ShowPageSizeDropDown
    {
        get { return plhPageSizeDropDown.Visible; }
        set { plhPageSizeDropDown.Visible = value; }
    }

    public bool ShowPageNavigationButtons
    {
        get { return plhPageNavButtons.Visible; }
        set { plhPageNavButtons.Visible = value; }
    }

    public bool ShowPageNumberLinks
    {
        get { return plhPageNumberLinks.Visible; }
        set { plhPageNumberLinks.Visible = value; }
    }

    public int ItemCount
    {
        get
        {
            object itemCount = ViewState["ItemCount"];
            return itemCount == null ? 0 : (int)itemCount;
        }
        set
        {
            ViewState["ItemCount"] = value;
            Calculate();
        }
    }

    public int? PageSize
    {
        get
        {
            return StringHelper.ParseInt(ddlPageSize.SelectedValue);
        }
        set
        {
            ListItem listItem = ddlPageSize.Items.FindByValue(value.ToString());
            if (listItem != null)
            {
                ddlPageSize.ClearSelection();
                listItem.Selected = true;
            }
            else
            {
                throw new NotSupportedException("The PageSize must be 10, 25, 50, 100 or All (null).");
            }
            Calculate();
        }
    }

    public int PageIndex
    {
        get
        {
            object pageIndex = ViewState["PageIndex"];
            return pageIndex == null ? 0 : (int)pageIndex;
        }
        set
        {
            ViewState["PageIndex"] = value;
            Calculate();
        }
    }

    public int PageCount
    {
        get
        {
            if (!this.PageSize.HasValue)
                return 1;

            return (int)Math.Ceiling((double)this.ItemCount / (double)this.PageSize);
        }
    }

    public int PageButtonCount
    {
        get
        {
            object pageButtonCount = ViewState["PageButtonCount"];
            return pageButtonCount == null ? 10 : (int)pageButtonCount;
        }
        set
        {
            ViewState["PageButtonCount"] = value;
        }
    }

    private void RefreshComponents()
    {
        Calculate();

        if (ShowPageSizeDropDown || this.LinkedPaginator == null)
        {
            OnPageSizeChanged(new EventArgs());
        }
    }

    public void Calculate()
    {
        //plhPageNumberLinks.Visible = (this.PageCount > 0);

        int pageCount = this.PageCount;
        if (pageCount == 0)
            pageCount = 1;

        int pageIndex = this.PageIndex;
        if (pageIndex >= pageCount)
        {
            pageIndex = pageCount - 1;

            ViewState["PageIndex"] = pageIndex; //this.PageIndex = pageIndex;
        }

        int pageButtonCount = this.PageButtonCount;

        int startPageIndex = 0;
        int endPageIndex = pageCount - 1;
        if (pageButtonCount > 0)
        {
            startPageIndex = (pageIndex / pageButtonCount) * pageButtonCount;
            endPageIndex = startPageIndex + pageButtonCount - 1;
            if (endPageIndex > pageCount - 1)
                endPageIndex = pageCount - 1;
        }

        plhPrevPageGroup.Visible = startPageIndex != 0;
        plhNextPageGroup.Visible = endPageIndex != pageCount - 1;

        lnkPrevPage.Visible = pageIndex != 0;
        lnkNextPage.Visible = pageIndex != pageCount - 1;

        IList<int> pageIndexes = new List<int>();
        for (int i = startPageIndex; i <= endPageIndex; i++)
        {
            pageIndexes.Add(i);
        }

        rptPageNumber.DataSource = pageIndexes;
        rptPageNumber.DataBind();
    }

    protected void ddlPageSize_SelectedIndexChanged(object sender, EventArgs e)
    {
        Calculate();
        OnPageSizeChanged(new EventArgs());
        OnPageIndexChanged(new EventArgs());
    }

    protected void lnkPrevPageGroup_Click(object sender, EventArgs e)
    {
        int pageIndex = this.PageIndex;
        this.PageIndex = (pageIndex / PageButtonCount) * PageButtonCount - 1;

        OnPageIndexChanged(new EventArgs());
    }

    protected void lnkNextPageGroup_Click(object sender, EventArgs e)
    {
        int pageIndex = this.PageIndex;
        this.PageIndex = ((pageIndex / PageButtonCount) + 1) * PageButtonCount;

        OnPageIndexChanged(new EventArgs());
    }

    protected void lnkPrevPage_Click(object sender, EventArgs e)
    {
        this.PageIndex = this.PageIndex - 1;

        OnPageIndexChanged(new EventArgs());
    }

    protected void lnkNextPage_Click(object sender, EventArgs e)
    {
        this.PageIndex = this.PageIndex + 1;

        OnPageIndexChanged(new EventArgs());
    }

    protected void rptPageNumber_ItemCommand(object source, RepeaterCommandEventArgs e)
    {
        if (e.CommandName == "GoToPage")
        {
            this.PageIndex = Convert.ToInt32(e.CommandArgument);

            OnPageIndexChanged(new EventArgs());
        }
    }

    protected void rptPageNumber_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            int pageIndex = (int)e.Item.DataItem;

            LinkButton lnkPageNumber = (LinkButton)e.Item.FindControl("lnkPageNumber");
            lnkPageNumber.CommandArgument = pageIndex.ToString();
            lnkPageNumber.Text = String.Format("{0}", pageIndex + 1);
            lnkPageNumber.Visible = (pageIndex != this.PageIndex);

            Label lblPageNumber = (Label)e.Item.FindControl("lblPageNumber");
            lblPageNumber.Text = String.Format("{0}", pageIndex + 1);
            lblPageNumber.Visible = (pageIndex == this.PageIndex);
        }
    }
}